home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d16 / winvn060.arc / WVSCREEN.C < prev    next >
C/C++ Source or Header  |  1991-07-01  |  13KB  |  412 lines

  1. /*-- First Line of WVSCREEN.C -- Contains Screen-related functions.  */
  2.  
  3. #include "windows.h"
  4. #include "wvglob.h"
  5. #include "winvn.h"
  6.  
  7. /*--- function ScreenDown ----------------------------------------------
  8.  *
  9.  *  Advance a pointer "nLines" lines through the textlines.
  10.  *  However, do not go so far that less than LinesOnScreen lines
  11.  *  are left past the pointer.
  12.  *
  13.  *  This is used to implement "PageDown" and "LineDown" functions.
  14.  *
  15.  *    Entry    nLines         Number of lines to move the pointer.
  16.  *             LinesOnScreen  is the number of lines on the screen.
  17.  *             BlockPtr       Pointer to block containing line.
  18.  *             LinePtr        Pointer to the given line.
  19.  *
  20.  *    Exit     BlockPtr and LinePtr (may) have been moved to a new line.
  21.  *             LinesAdvanced  is the number of lines actually moved--can be
  22.  *                            less than nLines if we hit the top of the
  23.  *                            last screen.
  24.  */
  25. void
  26. ScreenDown(nLines,LinesOnScreen,BlockPtr,LinePtr,LinesAdvanced)
  27. int nLines;
  28. int LinesOnScreen;
  29. TypBlock far **BlockPtr;
  30. TypLine far **LinePtr;
  31. int *LinesAdvanced;
  32. {
  33.    TypBlock far *MyBlock = *BlockPtr;
  34.    TypLine far *MyLine = *LinePtr;
  35.    int LinesGone;
  36.    int TestAdvance;
  37.    HANDLE hBlock, hBlockGarbage;
  38.    unsigned int Offset, OffsetGarbage;
  39.    TypLineID LineIDGarbage, MyLineID;
  40.  
  41.    /* Skip forward nLines, plus one screen's worth, just to see      */
  42.    /* if there are enough lines ahead of us in the document.         */
  43.  
  44.    PtrToOffset(MyBlock,MyLine,&hBlock,&Offset,&MyLineID);
  45.    TestAdvance = nLines + LinesOnScreen - 1;
  46.    for(LinesGone=TestAdvance; LinesGone && NextLine(&MyBlock,&MyLine);
  47.      LinesGone--);
  48.    UnlockLine(MyBlock,MyLine,&hBlockGarbage,&OffsetGarbage,&LineIDGarbage);
  49.  
  50.    nLines -= LinesGone;
  51.    if(nLines<0) nLines = 0;
  52.    *LinesAdvanced = nLines;
  53.  
  54.    LockLine(hBlock,Offset,MyLineID,&MyBlock,&MyLine);
  55.    while(nLines--) {
  56.       NextLine(BlockPtr,LinePtr);
  57.    }
  58. }
  59.  
  60. /*--- function ScreenUp ----------------------------------------------
  61.  *
  62.  *  Back up a pointer "nLines" lines through the textlines.
  63.  *  However, do not go past the beginning of the document.
  64.  *
  65.  *  This is used to implement "PageUp" and "LineUp" functions.
  66.  *
  67.  *    Entry    nLines         Number of lines to move the pointer.
  68.  *             BlockPtr       Pointer to block containing line.
  69.  *             LinePtr        Pointer to the given line.
  70.  *
  71.  *    Exit     BlockPtr and LinePtr (may) have been moved to a new line.
  72.  *             LinesBackedUp  is the number of lines actually moved--can be
  73.  *                            less than nLines if we hit beginning of doc.
  74.  */
  75. void
  76. ScreenUp(nLines,BlockPtr,LinePtr,LinesBackedUp)
  77. int nLines;
  78. TypBlock far **BlockPtr;
  79. TypLine far **LinePtr;
  80. int *LinesBackedUp;
  81. {
  82.    *LinesBackedUp = 0;
  83.  
  84.    while(nLines-- && PrevLine(BlockPtr,LinePtr)) {
  85.       (*LinesBackedUp)++;
  86.    }
  87. }
  88.  
  89. /*--- function ScrollIt ----------------------------------------------
  90.  *
  91.  *  Perform a scrolling action.
  92.  *
  93.  *    Entry    Document points to a document
  94.  *             wParam   is the wParam argument given from a WM_VSCROLL
  95.  *                      window message.  (One of the SB_ symbols.)
  96.  *             lParam   is the lParam argument.
  97.  */
  98. void
  99. ScrollIt(Document,wParam,lParam)
  100. TypDoc *Document;
  101. WORD wParam;
  102. DWORD lParam;
  103. {
  104.    TypBlock far *BlockPtr, far *NewBlockPtr;
  105.    TypLine  far *LinePtr, far *NewLinePtr;
  106.    int LinesGone;
  107.    unsigned int LineOrd;
  108.    RECT Rect;
  109.  
  110.    switch(wParam){
  111.       case SB_LINEUP:
  112.          /* Move up a line by scrolling the window down one line     */
  113.          /* and introducing 1 new line at the top.                   */
  114.          LockLine(Document->hCurTopScBlock,Document->TopScOffset,Document->TopScLineID,&BlockPtr,&LinePtr);
  115.          ScreenUp(1,&BlockPtr,&LinePtr,&LinesGone);
  116.         doscrollup:;
  117.          if(LinesGone) {
  118.             Rect.left = 0;
  119.             Rect.right = Document->ScXWidth;
  120.             Document->TopLineOrd -= LinesGone;
  121. #if 0
  122.             Rect.top = TopSpace;
  123.             Rect.bottom = Document->ScYHeight;
  124.             ScrollWindow(Document->hDocWnd,0,LinesGone*LineHeight,&Rect,&Rect);
  125. #endif
  126.             ScrollWindow(Document->hDocWnd,0,LinesGone*LineHeight,NULL,NULL);
  127. #ifdef MAC
  128.             Rect.top = 0;
  129.             Rect.bottom = LinesGone*LineHeight;
  130. #else
  131.             Rect.top = TopSpace;
  132.             Rect.bottom = TopSpace+LinesGone*LineHeight;
  133. #endif
  134.             InvalidateRect(Document->hDocWnd,&Rect,FALSE);
  135.             /* Make sure garbage at bottom is erased in WM_PAINT processing */
  136.             Rect.top = TopSpace + Document->ScYLines*LineHeight;
  137.             Rect.bottom = Document->ScYHeight;
  138.             InvalidateRect(Document->hDocWnd,&Rect,FALSE);
  139.          }
  140.          break;
  141.  
  142.       case SB_LINEDOWN:
  143.          LockLine(Document->hCurTopScBlock,Document->TopScOffset,Document->TopScLineID,&BlockPtr,&LinePtr);
  144.          ScreenDown(1,Document->ScYLines,&BlockPtr,&LinePtr,&LinesGone);
  145.        doscrolldown:;
  146.          if(LinesGone) {
  147.             Document->TopLineOrd += LinesGone;
  148.             Rect.left = 0;
  149.             Rect.right = Document->ScXWidth;
  150. #if 0
  151.             Rect.top = TopSpace;
  152.             Rect.bottom = Document->ScYHeight;
  153.             ScrollWindow(Document->hDocWnd,0,-LinesGone*LineHeight,&Rect,&Rect);
  154. #endif
  155.             ScrollWindow(Document->hDocWnd,0,-LinesGone*LineHeight,NULL,NULL);
  156. #ifdef MAC
  157.             Rect.top = (Document->ScYLines-LinesGone)*LineHeight;
  158.             Rect.bottom = Document->ScYHeight;
  159. #else
  160.             Rect.top = TopSpace + (Document->ScYLines-LinesGone)*LineHeight;
  161.             Rect.bottom = Document->ScYHeight;
  162. #endif
  163.             InvalidateRect(Document->hDocWnd,&Rect,FALSE);
  164.             /* Make sure garbage at top is erased in WM_PAINT processing */
  165.             Rect.top = 0;
  166.             Rect.bottom = TopSpace;
  167.             InvalidateRect(Document->hDocWnd,&Rect,FALSE);
  168.          }
  169.          break;
  170.  
  171.       case SB_PAGEUP:
  172.          LockLine(Document->hCurTopScBlock,Document->TopScOffset,Document->TopScLineID,&BlockPtr,&LinePtr);
  173.          ScreenUp(Document->ScYLines-1,&BlockPtr,&LinePtr,&LinesGone);
  174.          Document->TopLineOrd -= LinesGone;
  175.          InvalidateRect(Document->hDocWnd, NULL, FALSE);
  176.          break;
  177.  
  178.       case SB_PAGEDOWN:
  179.          LockLine(Document->hCurTopScBlock,Document->TopScOffset,Document->TopScLineID,&BlockPtr,&LinePtr);
  180.          ScreenDown(Document->ScYLines-1,Document->ScYLines,
  181.           &BlockPtr,&LinePtr,&LinesGone);
  182.          Document->TopLineOrd += LinesGone;
  183.          InvalidateRect(Document->hDocWnd, NULL, FALSE);
  184.          break;
  185.  
  186.       case SB_THUMBPOSITION:
  187.          LineOrd = LOWORD(lParam);
  188.          if(!FindLineOrd(Document,LineOrd,&BlockPtr,&LinePtr)) {
  189.             return;
  190.          }
  191.        doposition:;
  192.          Document->TopLineOrd = LineOrd;
  193.          InvalidateRect(Document->hDocWnd, NULL, FALSE);
  194.          break;
  195.  
  196.       case SB_THUMBTRACK:
  197.          LineOrd = LOWORD(lParam);
  198.          if(!FindLineOrd(Document,LineOrd,&BlockPtr,&LinePtr)) {
  199.             return;
  200.          }
  201.          LinesGone = LineOrd - Document->TopLineOrd;
  202.          if(LinesGone > 0) {
  203.             if(LinesGone >= (Document->ScYLines-1)) {
  204.                goto doposition;
  205.             } else {
  206.                goto doscrolldown;
  207.             }
  208.          } else if(LinesGone < 0) {
  209.             LinesGone = -LinesGone;
  210.             if(LinesGone >= (Document->ScYLines-1)) {
  211.                goto doposition;
  212.             } else {
  213.                goto doscrollup;
  214.             }
  215.          }
  216.          break;
  217.  
  218.       default:
  219.          return;
  220.          break;
  221.    }
  222.  
  223.    UnlockLine(BlockPtr,LinePtr,&(Document->hCurTopScBlock),
  224.      &(Document->TopScOffset),&(Document->TopScLineID));
  225. #ifdef MAC
  226. /* SendMessage(Document->hDocWnd,WM_PAINT,0,0L); */
  227.    MyUpdateWindow(Document->hDocWnd);
  228. #endif
  229.  
  230. }
  231.  
  232. /*--- function LineOnScreen ----------------------------------------
  233.  *
  234.  *  Determine whether a given line is displayed on the screen.
  235.  *  If it is, give the ordinal line number on the screen.
  236.  *
  237.  *  Entry   Doc         points to the document.
  238.  *          hTargBlock  is the handle of the block containing the line.
  239.  *          TargOffset  is the offset of the target line.
  240.  *          TargLineID  is the line's ID.
  241.  *
  242.  *  Exit    returns -1 if the line is not on the screen, else
  243.  *          the ordinal line number (0 = top line, etc.)
  244.  */
  245. int
  246. LineOnScreen(Doc,hTargBlock,TargOffset,TargLineID)
  247. TypDoc *Doc;
  248. HANDLE hTargBlock;
  249. unsigned int TargOffset;
  250. TypLineID TargLineID;
  251. {
  252.    TypBlock far *CurBlockPtr, far *TargBlockPtr;
  253.    TypLine  far *CurLinePtr,  far *TargLinePtr;
  254.    int iline;
  255.    BOOL found=FALSE;
  256.    HANDLE hBlock;
  257.    unsigned int Offset;
  258.    TypLineID  MyLineID;
  259.  
  260.    LockLine(Doc->hCurTopScBlock,Doc->TopScOffset,Doc->TopScLineID,&CurBlockPtr,&CurLinePtr);
  261.    LockLine(hTargBlock,TargOffset,TargLineID,&TargBlockPtr,&TargLinePtr);
  262.  
  263.    for(iline=0; !found && iline < Doc->ScYLines; iline++) {
  264.       found = (TargLinePtr == CurLinePtr);
  265.       if(!found) {
  266.          NextLine(&CurBlockPtr,&CurLinePtr);
  267.       }
  268.    }
  269.  
  270.    UnlockLine(CurBlockPtr,CurLinePtr,&hBlock,&Offset,&MyLineID);
  271.    UnlockLine(TargBlockPtr,TargLinePtr,&hBlock,&Offset,&MyLineID);
  272.  
  273.    if(!found) iline = 0;
  274.    return(iline-1);
  275. }
  276.  
  277. /*--- function NextWindow ----------------------------------------------
  278.  *
  279.  *  Makes another window the active window with input focus.
  280.  *  This function would typically be used to implement a keystroke
  281.  *  (usually F6) that switches windows.
  282.  *
  283.  *    Entry    Doc   points to the current document.
  284.  */
  285. void
  286. NextWindow(Doc)
  287. TypDoc *Doc;
  288. {
  289.    int idoc;
  290.    int trydoctype;
  291.    TypDoc *NewDoc;
  292.  
  293.    /* First, locate the current window in our data structures.       */
  294.  
  295.    switch(Doc->DocType) {
  296.       case DOCTYPE_NET:
  297.          idoc = 0;
  298.          trydoctype = DOCTYPE_GROUP;
  299.          break;
  300.       case DOCTYPE_GROUP:
  301.          for(idoc=0; idoc < MAXGROUPWNDS && Doc != &(GroupDocs[idoc]); idoc++);
  302.          if(idoc >= MAXGROUPWNDS) {
  303.             MessageBox(Doc->hDocWnd,"Error finding next window", "System error",MB_ICONHAND|MB_OK);
  304.          }
  305.          trydoctype = DOCTYPE_GROUP;
  306.          idoc++;
  307.          break;
  308.       case DOCTYPE_ARTICLE:
  309.          for(idoc=0; idoc < MAXARTICLEWNDS && Doc != &(ArticleDocs[idoc]); idoc++);
  310.          if(idoc >= MAXARTICLEWNDS) {
  311.             MessageBox(Doc->hDocWnd,"Error finding next window", "System error",MB_ICONHAND|MB_OK);
  312.          }
  313.          trydoctype = DOCTYPE_ARTICLE;
  314.          idoc++;
  315.          break;
  316.    }
  317.  
  318.    /* Now, find the next window in the sequence.                     */
  319.  
  320.    if(trydoctype == DOCTYPE_GROUP) {
  321.       for(;idoc < MAXGROUPWNDS ; idoc++) {
  322.          if(GroupDocs[idoc].InUse) {
  323.             NewDoc = ActiveGroupDoc = &(GroupDocs[idoc]);
  324.             goto foundit;
  325.          }
  326.       }
  327.       idoc = 0;
  328.    }
  329.  
  330.    /* Not found yet--try to find an Article doc.                     */
  331.  
  332.    for(;idoc < MAXARTICLEWNDS ; idoc++) {
  333.       if(ArticleDocs[idoc].InUse) {
  334.          NewDoc = ActiveArticleDoc = &(ArticleDocs[idoc]);
  335.          goto foundit;
  336.       }
  337.    }
  338.  
  339.    /* Still not found--just make the Net document the next one.      */
  340.  
  341.    NewDoc = &NetDoc;
  342.  
  343. foundit:;
  344.  
  345.    SetActiveWindow(NewDoc->hDocWnd);
  346.    SetFocus(NewDoc->hDocWnd);
  347.  
  348. }
  349.  
  350. /*--- function AdjustScTop -----------------------------------
  351.  *
  352.  *  Adjust the top line of the screen so that a given line is sure
  353.  *  to appear on the screen.
  354.  *  Don't do anything if the document is one screen's length or smaller.
  355.  *
  356.  *    Entry
  357.  *             BlockPtr and LinePtr  point to the line we want to
  358.  *                      make sure is visible.
  359.  *
  360.  *    Exit     Doc's TopSc fields have been set to ensure that
  361.  *               the line will appear on the screen.
  362.  *             The line has been unlocked.
  363.  */
  364.  
  365. void
  366. AdjustTopSc(BlockPtr,LinePtr)
  367. TypBlock far *BlockPtr;
  368. TypLine far *LinePtr;
  369. {
  370.    unsigned int lineord;
  371.    TypDoc *Doc;
  372.    HANDLE hBlock;
  373.    unsigned int Offset;
  374.    TypLineID MyLineID;
  375.  
  376.    Doc = BlockPtr->OwnerDoc;
  377.    if(Doc->TotalLines > Doc->ScYLines) {
  378.       lineord = WhatLine(BlockPtr,LinePtr);
  379.  
  380.       while(lineord > Doc->TotalLines - Doc->ScYLines) {
  381.          PrevLine(&BlockPtr,&LinePtr);
  382.          lineord--;
  383.       }
  384.       Doc->TopLineOrd = lineord;
  385.       UnlockLine(BlockPtr,LinePtr,&(Doc->hCurTopScBlock),
  386.          &(Doc->TopScOffset),&(Doc->TopScLineID));
  387.    } else {
  388.       UnlockLine(BlockPtr,LinePtr,&hBlock,&Offset,&MyLineID);
  389.    }
  390. }
  391.  
  392. /*--- function ScreenToTop -------------------------------------
  393.  *
  394.  *  Sets a document so that the screen is scrolled to the top.
  395.  *
  396.  *  Entry   Doc     points to the document.
  397.  *
  398.  *  Exit     The document has been set to display starting at
  399.  *               the first line.
  400.  */
  401.  
  402. void
  403. ScreenToTop(TypDoc *Doc)
  404. {
  405.     Doc->hCurTopScBlock = Doc->hFirstBlock;
  406.     Doc->TopScOffset = sizeof(TypBlock);
  407.     Doc->TopScLineID = 0;
  408.     Doc->TopLineOrd = 0;
  409.  
  410. }
  411. /*-- Last Line of WVSCREEN.C ----------------- */
  412.